package net.wangds.auth.department.ctrl;

import net.wangds.auth.department.comp.GeneralDepartmentComp;
import net.wangds.auth.department.entity.GeneralDepartmentEntity;
import net.wangds.auth.department.entity.GeneralDepartmentJobRef;
import net.wangds.auth.department.entity.GeneralDepartmentRoleRef;
import net.wangds.auth.job.comp.GeneralJobComp;
import net.wangds.auth.role.comp.GeneralRoleComp;
import net.wangds.auth.user.comp.GeneralUserComp;
import net.wangds.data.Tree;
import net.wangds.jpa.Sorts;
import net.wangds.jpa.comp.AbstractRemovedComp;
import net.wangds.jpa.ctrl.AbstractJpaCompCtrl;
import net.wangds.web.entrypoint.BaseMultipleResp;
import net.wangds.web.entrypoint.BaseResp;
import net.wangds.web.entrypoint.PagingForm;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.transaction.Transactional;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/department")
public class DepartmentCtrl extends AbstractJpaCompCtrl<GeneralDepartmentEntity> {

    @SuppressWarnings("unused")
    @Autowired
    private GeneralDepartmentComp mmCmpDept;

    @SuppressWarnings("unused")
    @Autowired
    private GeneralUserComp mmCmpUser;

    @SuppressWarnings("unused")
    @Autowired
    private GeneralJobComp mmCmpJob;

    @SuppressWarnings("unused")
    @Autowired
    private GeneralRoleComp mmCmpRole;

    @Override
    protected AbstractRemovedComp<GeneralDepartmentEntity> fetchJpaComp() {
        return mmCmpDept;
    }

    @Override
    protected BaseMultipleResp<GeneralDepartmentEntity> listWithKeywords(PagingForm page) {
        return mmConvPage2Resp.convert(mmCmpDept.findByKeywords(page.getKeywords(), mmConvPf2Pr.convert(page)));
    }


    /**
     * 获得指定机构id的子机构树.
     * @param rootDepId 根机构.
     * @return 机构树.
     */
    @SuppressWarnings("unused")
    @RequestMapping(value="/tree/{rootDepId}", method = RequestMethod.POST)
    public BaseMultipleResp<GeneralDepartmentEntity> tree(
            @PathVariable(value="rootDepId", required = false) String rootDepId
    ){

        List<GeneralDepartmentEntity> depts = mmCmpDept.findAll(Sorts.createTm_asc);

        List<GeneralDepartmentEntity> trees = Tree.trees(depts);

        if(StringUtils.equals("-1",rootDepId)){
            return BaseMultipleResp.list(trees);
        }else {
            return BaseMultipleResp.list(depts.stream().filter(c -> StringUtils.equals(rootDepId, c.getId())).collect(Collectors.toList()));
        }
    }


    @SuppressWarnings("unused")
    @RequestMapping(value="/bindUser/{deptId}/{uid}", method = RequestMethod.POST)
    public BaseResp<Boolean> bindUser(
            @PathVariable("deptId") String deptId,
            @PathVariable("uid") String uid
    ) {
        mmCmpDept.findById(deptId).ifPresent(dept->
                        mmCmpUser.findById(uid).ifPresent(usr-> mmCmpDept.bindUser(dept, usr))
                );

        return BaseResp.of(true);
    }


    @SuppressWarnings("unused")
    @RequestMapping(value="/unbindUser/{deptId}/{uid}", method = RequestMethod.POST)
    public BaseResp<Boolean> unbindUser(
            @PathVariable("deptId") String deptId,
            @PathVariable("uid") String uid) {
        mmCmpDept.findById(deptId).ifPresent(dept->
                mmCmpUser.findById(uid).ifPresent(usr-> mmCmpDept.unbindUser(dept, usr))
        );
        return BaseResp.of(true);
    }


    @SuppressWarnings("unused")
    @RequestMapping(value="/bindJob/{deptId}/{jobId}", method = RequestMethod.POST)
    public BaseResp<Boolean> bindJob(
            @PathVariable("deptId") String deptId,
            @PathVariable("jobId") String jobId){

        mmCmpDept.findById(deptId).ifPresent(dept->
                mmCmpJob.findById(jobId).ifPresent(job-> mmCmpDept.bindJob(dept, job))
        );

        return BaseResp.of(true);
    }


    @SuppressWarnings("unused")
    @RequestMapping(value="/unbindJob/{deptId}/{jobId}", method = RequestMethod.POST)
    public BaseResp<Boolean> unbindJob(
            @PathVariable("deptId") String deptId,
            @PathVariable("jobId") String jobId){
        mmCmpDept.findById(deptId).ifPresent(dept->
                mmCmpJob.findById(jobId).ifPresent(job-> mmCmpDept.unbindJob(dept, job))
        );
        return BaseResp.of(true);
    }


    @SuppressWarnings("unused")
    @RequestMapping(value="/bindRole/{deptId}/{roleId}", method = RequestMethod.POST)
    public BaseResp<Boolean> bindRole(
            @PathVariable("deptId") String deptId,
            @PathVariable("roleId") String roleId){

        mmCmpDept.findById(deptId).ifPresent(dept->
                mmCmpRole.findById(roleId).ifPresent(role-> mmCmpDept.bindRole(dept, role))
        );

        return BaseResp.of(true);
    }

    @SuppressWarnings("unused")
    @RequestMapping(value="/unbindRole/{deptId}/{roleId}", method = RequestMethod.POST)
    public BaseResp<Boolean> unbindRole(
            @PathVariable("deptId") String deptId,
            @PathVariable("roleId") String roleId){

        mmCmpDept.findById(deptId).ifPresent(dept->
                mmCmpRole.findById(roleId).ifPresent(role-> mmCmpDept.unbindRole(dept, role))
        );
        return BaseResp.of(true);
    }

    @SuppressWarnings("unused")
    @Transactional
    @RequestMapping(value = "/{deptId}/jobIds", method = RequestMethod.POST)
    public BaseResp<List<String>> loadDeptJobIds(
            @PathVariable("deptId") String deptId) {
        BaseResp<List<String>> res = BaseResp.of(null);
        mmCmpDept.findById(deptId).ifPresent(dept ->
                res.body(mmCmpDept.findDeptJobRef(dept).stream().map(GeneralDepartmentJobRef::getJobId).collect(Collectors.toList()))
        );
        return res;
    }

    @SuppressWarnings("unused")
    @Transactional
    @RequestMapping(value = "/{deptId}/roleIds", method = RequestMethod.POST)
    public BaseResp<? extends Collection<String>> loadDeptRoleIds(
            @PathVariable("deptId") String deptId) {
        BaseResp<List<String>> res = BaseResp.of(null);
        mmCmpDept.findById(deptId).ifPresent(dept ->
                res.body(mmCmpDept.findDeptRoleRef(dept).stream().map(GeneralDepartmentRoleRef::getRoleId).collect(Collectors.toList()))
        );
        return res;
    }



}
